﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;

namespace ThreadStaticMethod
{
    class Program
    {
        //static void Main(string[] args)
        //{
        //    //Thread.AllocateDataSlot();
        //    //给线程分配了卡槽
        //    var ads=Thread.AllocateNamedDataSlot("user");
        //    //在主线程设置数据
        //    Thread.SetData(ads,"Jet");
        //    var t = new Thread(() => {
        //        //工作线程是读不到主线程设置的数据，反之也是
        //        Console.WriteLine($"工作线程读取:{Thread.GetData(ads)}");
        //    });
        //    t.Start();
        //    Console.WriteLine($"主线程读取:{Thread.GetData(ads)}");
        //    Console.ReadKey();

        //}

        //// 和上面性能有所提升
        //[ThreadStatic]
        //static string username = string.Empty;
        //static void Main(string[] args)
        //{
        //    username = "Jet";
        //    var t = new Thread(() => {
        //        Console.WriteLine($"工作线程读取:{username}");
        //    });
        //    t.Start();
        //    Console.WriteLine($"主线程读取:{username}");
        //    Console.ReadKey();

        //}


        //static void Main(string[] args)
        //{
        //    ThreadLocal<string> local= new ThreadLocal<string>();
        //    local.Value = "Jet";

        //    var t = new Thread(() =>
        //    {
        //        Console.WriteLine($"工作线程读取:{local.Value}");
        //    });
        //    t.Start();
        //    Console.WriteLine($"主线程读取:{local.Value}");
        //    Console.ReadKey();

        //}
        // 以上的数据都是存放在线程坏境块中的
        // 属于线程空间的开销（TLS）thread local storage


        /**debug 模式下和releas 模式下性能还是有很大的差异**/
        //static void Main(string[] args)
        //{
        //    var path = Environment.CurrentDirectory + "//1.txt";
        //    var txt = File.ReadAllText(path);
        //    var list = txt.Select(x => Convert.ToInt32(x)).ToList();
        //    for (int i = 0; i < 5; i++)
        //    {
        //        var watch = Stopwatch.StartNew();
        //        var mylist = BubbleSort(list);
        //        watch.Stop();
        //        Console.WriteLine(watch.Elapsed.TotalSeconds);
        //    }
        //    Console.ReadKey();

        //}
        //static List<int> BubbleSort(List<int> list)
        //{
        //    int temp;
        //    //第一层循环： 表明要比较的次数，比如list.count个数，肯定要比较count-1次
        //    for (int i = 0; i < list.Count - 1; i++)
        //    {
        //        //list.count-1：取数据最后一个数下标，
        //        //j>i: 从后往前的的下标一定大于从前往后的下标，否则就超越了。
        //        for (int j = list.Count - 1; j > i; j--)
        //        {
        //            //如果前面一个数大于后面一个数则交换
        //            if (list[j - 1] > list[j])
        //            {
        //                temp = list[j - 1];
        //                list[j - 1] = list[j];
        //                list[j] = temp;
        //            }
        //        }
        //    }
        //    return list;
        //}


        static void Main(string[] args)
        {
            var isStop = 0;
            var t = new Thread(() =>
            {
                var isSuccess = false;
                while (isStop == 0)
                {
                    /**
                     * 在此方法之前的写入都要从cup cache 中更新memory
                     * 之后读取都要从memory中读取，
                     * ***/
                   // Thread.MemoryBarrier();

                    //读取字段值  无论处理器数目，或者处理器缓存状态如何，该值都是有计算机写入最新的值
                    Thread.VolatileRead(ref isStop);
                    isSuccess = !isSuccess;
                }
            });
            t.Start();
            Thread.Sleep(1000);
            // 程序启动后，子线程执行了一会，这里已经设置为1，此时应该退出while
            // 但是子线程在release里面读取的是cpu里面的 缓存值，它根本不知道值已经修改了，所以主线程结束不了，子线程一直运行
            // 主要就是因为是2个线程读取修改共享变量

            isStop = 1;
            Console.WriteLine(isStop);
            t.Join();// 阻塞主线程，让子执行完
            Console.WriteLine($"主线程执行完");
            Console.ReadKey();

        }





    }
}
